//    Copyright (C) Kherty.  All rights reserved.
using System;
using System.Collections.Generic;
using OpenLS.Chart;
using OpenLS.Core.Serialization;
using OpenLS.Spreadsheet.Expressions;

namespace OpenLS.Spreadsheet.Chart
{
    class RangeStringReference: StringReference
    {
        public RangeStringReference()
        {

        }
        public RangeStringReference(EvaluationContext context, Expression expression)
        {
            SetRange(new InvalidRange(context, expression));
        }

        public RangeStringReference(Range range)
        {
            RangeReference rr = range.ToReference();
            Expression exp = new RangeReferenceExpression(rr, rr.Worksheet);
            SetRange(new InvalidRange(new WorksheetEvaluationContext(range.Worksheet), exp));
        }


        protected override void ReadXmlCore(ReadContext context)
        {
            using (ReadContext c = context.Read("strRef"))
            {
                string formula = c.ReadElementString("f");
                Workbook workbook = context.GetData<Workbook>();
                Worksheet worksheet = context.GetData<Worksheet>();
                c.GetData<WorkbookResolver>().ResolveActions.Add //\\workbook.TempReader.ResolveActions.Add
    (
    delegate
    {
        if (worksheet != null)
            SetRange(new InvalidRange(worksheet, formula));
        else
            SetRange(new InvalidRange(workbook, formula)); //\\ notsute it should happen
    });

                this.cache = c.ReadOptionalElementAs<StringData>("strCache");
                Extension = c.ReadOptionalElement<ExtensionElement>("extLst");
            }
        }

        private void SetRange(InvalidRange invalidRange)
        {
            range = invalidRange;
            if (invalidRange.Range == null)
                return;
            cache = null;
            invalidRange.Range.CellValueChanged += range_CellValueChanged;
            NotifyPropertyChanged("Values");

        }
        public override IEnumerable<StringValue> StringValues
        {
            get
            {
                if (range.Range == null)
                {
                    if (cache == null)
                        yield break;
                    foreach (var data in cache.StringValues)
                    {
                        yield return data;
                    }
                }
                cache = null;
                foreach (Cell cell in range.Range.GetNonEmptyCells())
                {
                    if (cell.Value == null)
                        continue;
                    string s = cell.FormattedValue; //\\
                    {
                        StringValue v = new StringValue();
                        v.Index = (cell.Row.Index - range.Range.TopLeftCell.Row.Index) + (cell.Column.Index - range.Range.TopLeftCell.Column.Index);
                        v.Value = s;
                        v.Parent = this;
                        yield return v;
                    }
                }
            }
        }

        protected override void WriteData(WriteContext context)
        {
            
        }

        void range_CellValueChanged(object sender, EventArgs e)
        {
            this.OnValueChanged();
        }
        InvalidRange range;
        private StringData cache;

        public override string Formula
        {
            get
            {
                return range.Formula;
            }
        }
    }
}
